package org.argeproje.resim.property;

import org.argeproje.resim.proc.data.KernelDA;
import org.argeproje.resim.ui.parts.CellStringValidator;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.views.properties.PropertyDescriptor;


public class MatrixPropertyDescriptor extends PropertyDescriptor {
	private KernelDA _kernel;
	
	public MatrixPropertyDescriptor(Object id, String displayName,KernelDA kernel) {
		super(id, displayName);
		_kernel = kernel;
	}
	
	public CellEditor createPropertyEditor(Composite parent) {
        CellEditor editor = new MatrixCellEditor(parent,_kernel);
        editor.setValidator(new CellStringValidator());   
        return editor;
	}

}

class MatrixCellEditor extends DialogCellEditor
{
	private KernelDA _kernel;
	public MatrixCellEditor(Composite parent,KernelDA kernel) {
        super(parent);
        _kernel = kernel;
     }

	@Override
	protected Object openDialogBox(Control cellEditorWindow) {
		MatrixDialog md = new MatrixDialog(cellEditorWindow.getShell(),_kernel);
		md.setBlockOnOpen(true);
		md.open();
        return md.getKernel().toString();
	}	
}

class MatrixDialog extends TitleAreaDialog
{
	private KernelDA _kernel;
	
	protected MatrixDialog(Shell parentShell,KernelDA kernel) {
		super(parentShell);
		_kernel = kernel;
	}
	
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		
		final Table table = new Table(composite, SWT.BORDER | SWT.MULTI);
	    //table.setLayoutData(new GridLayout(new GridData(SWT.FI)));
		table.setLinesVisible(true);

	    for(int colIndex = 0;colIndex<_kernel.getNCol();colIndex++)
	    {
	      TableColumn tc = new TableColumn(table, SWT.LEFT);
	      tc.setText(String.valueOf(colIndex+1));
	    }
	    table.setHeaderVisible(true);
	    
	    for(int rowIndex=0;rowIndex<_kernel.getNRow();rowIndex++)
	    {
	    	TableItem row = new TableItem(table, SWT.NONE);
	    	for(int colIndex=0;colIndex<_kernel.getNCol();colIndex++)
	    	{
	    		row.setText(colIndex, String.valueOf(_kernel.getValue(rowIndex, colIndex)));
	    	}
	    }
	    for(int colIndex = 0;colIndex<_kernel.getNCol();colIndex++)
	    {
	    	table.getColumn(colIndex).pack();
	    }
	    
	    final TableEditor editor = new TableEditor(table);
	    editor.horizontalAlignment = SWT.LEFT;
	    editor.grabHorizontal = true;
	    table.addListener(SWT.MouseDown, new Listener() {
	      public void handleEvent(Event event) {
	    	  
	        Rectangle clientArea = table.getClientArea();
	        Point pt = new Point(event.x, event.y);
	        int index = table.getTopIndex();	        
	        while (index < table.getItemCount()) {
	          boolean visible = false;
	          final int rowIndex = index;
	          final TableItem item = table.getItem(index);
	          for (int i = 0; i < table.getColumnCount(); i++) {
	        	  
	            Rectangle rect = item.getBounds(i);
	            if (rect.contains(pt)) {
	              final int column = i;
	              final Text text = new Text(table, SWT.NONE);
	              final int colIndex = i;
	              Listener textListener = new Listener() {
	                public void handleEvent(final Event e) {
	                  switch (e.type) {
	                  case SWT.FocusOut:
	                	  try
	                	  {
	                	    float f = Float.parseFloat(text.getText());
	                	    item.setText(column,String.valueOf(f));
	                	    _kernel.setValue(rowIndex, colIndex, f);
	                	  }catch(Exception exception)
	                	  {
	                		  
	                	  }
	                    text.dispose();
	                    break;
	                  case SWT.Traverse:
	                    switch (e.detail) {
	                    case SWT.TRAVERSE_RETURN:	                    	
	                    	try
		                	  {
		                	    float f = Float.parseFloat(text.getText());
		                	    item.setText(column,String.valueOf(f));
		                	    _kernel.setValue(rowIndex, colIndex, f);
		                	  }catch(Exception exception)
		                	  {
		                		  
		                	  }
	                    // FALL THROUGH
	                    case SWT.TRAVERSE_ESCAPE:
	                      text.dispose();
	                      e.doit = false;
	                    }
	                    break;
	                  }
	                }
	              };
	              text.addListener(SWT.FocusOut, textListener);
	              text.addListener(SWT.Traverse, textListener);
	              editor.setEditor(text, item, i);
	              text.setText(item.getText(i));
	              text.selectAll();
	              text.setFocus();
	              return;
	            }
	            if (!visible && rect.intersects(clientArea)) {
	              visible = true;
	            }
	          }
	          if (!visible)
	            return;
	          index++;
	        }
	        
	      }

	    });
	    //composite.pack();
		return composite;
	}
	
	protected Control createContents(Composite parent) {
	    Control contents = super.createContents(parent);
	    // Set the title
	    setTitle("Matrix");
	    // Set the message
	    //setMessage("This is a JFace dialog", IMessageProvider.INFORMATION);
	    return contents;
	  }
	
	public KernelDA getKernel(){return _kernel;}

}
